﻿package bipede.membres
{
	import events.MoveEvent;
	import fab.Utils;
	import flash.geom.Point;
	import fl.ik.*;	
	import fab.geom.*;
	import physic.Contrainte;
	import physic.Engine;
	import physic.Liaison;
	import physic.Obstacle;
	
	public class Pied
	{
		public var _support:Obstacle;
		public var squelette:Squelette;
		public var ikBone:IKBone;
		public var ikMoverTalon:IKMover;
		public var ikMoverOrteil:IKMover;
		public var ikMoverGenou:IKMover;

		//public var ikJoint:IKJoint;
		public var fixed:Segment;
		//public var position:Point = new Point(0, 0);
		
		private var _longueur:int = 0;
		public var liaison:Liaison;
		
		public function Pied( _squelette:Squelette, _ikBone:IKBone )
		{
			squelette = _squelette;
			ikBone = _ikBone;
			
			ikMoverGenou = new IKMover( ikBone.headJoint.parent, genou );
			ikMoverTalon = new IKMover( ikBone.headJoint, talon );
			ikMoverOrteil = new IKMover( ikBone.tailJoint, orteil );
			
			ikMoverTalon.limitByIteration = true;
			ikMoverTalon.iterationLimit = 4;
			ikMoverOrteil.limitByIteration = true;
			ikMoverOrteil.iterationLimit = 4;	
			ikMoverGenou.limitByIteration = true;
			ikMoverGenou.iterationLimit = 4;				
		}
		public function get support():Obstacle
		{
			return _support;
		}	
		public function set support(o:Obstacle):void
		{
			if ( _support != null )
			{
				Liaison.destroy( this, _support );
				liaison = null;
			}
			if ( o != null )
			{
				// Point de la projection orthogonale du Talon sur ce Support, dans Engine.espace
				
				var proj_talon:Point = o.plateforme.projection( Utils.PointLocalTransformation( talon, squelette, Engine.espace ) );
				
				// prise du vecteur de longueur pied et bonne orientation sur la plateforme
				o.plateforme.oriente_x();
				var vecteur:Point = o.plateforme.vecteur.clone();
				vecteur.normalize( ( squelette.orientation?1: -1 ) * longueur );
				
				// Segment plantaire sur la plateforme, dans le systeme de l'obstacle
			
				var plante_sur_plateforme:Segment = Utils.SegmentLocalTransformation( new Segment( proj_talon, proj_talon.add( vecteur ) ), Engine.espace, o.display );
			
				//var b:Liaison = 
				liaison = new Liaison( this, o, plante_sur_plateforme );
			}
			_support = o;
		}			
		public function get plante():Segment
		{
			return new Segment( talon, orteil );
		}		
		public function get talon():Point
		{
			return ikBone.headJoint.position;
		}
		public function get orteil():Point
		{
			return ikBone.tailJoint.position;
		}		
		public function get genou():Point
		{
			return ikBone.headJoint.parent.position;
		}
		public function get longueur():int
		{
			if ( _longueur == 0 ) _longueur = Point.distance( ikBone.headJoint.position, ikBone.tailJoint.position );
			return _longueur;
		}
		public function remove_support():void
		{
			support = null;
			liaison = null;
			
			/*
			var c2:Contrainte = squelette.contraintes[ ikBone.headJoint.name ];
			if ( c2 != null )
			{
				squelette.contraintes.split( squelette.contraintes.indexOf( ikBone.headJoint.name ) );
				//squelette.contraintes[ ikBone.headJoint.name ].remove();
				delete squelette.contraintes[ ikBone.headJoint.name ];
			}	
			*/
		}
		
		// mouvements
		
		public function pose( obstacle:Obstacle ):Segment
		{
			//trace(obstacle);
			support = obstacle;

			//var proj_genou:Point = support.plateforme.projection( squelette.localToGlobal( genou ) );
			var proj_orteil:Point = support.plateforme.projection( Utils.PointLocalTransformation( orteil, squelette , Engine.espace ) );
			var proj_talon:Point = support.plateforme.projection( Utils.PointLocalTransformation( talon, squelette , Engine.espace ) );
			
			/*
			var c2:Contrainte = squelette.contraintes[ ikBone.headJoint.name ];
			if ( c2 == null ) squelette.create_contrainte( proj_orteil, ikBone.name, ikBone.headJoint.parent.parent.bone.name );
			else c2.updatePoint( proj_orteil );
			*/
			
			//ikMoverGenou.moveTo( squelette.globalToLocal( proj_genou ) );
			ikMoverTalon.moveTo( Utils.PointLocalTransformation( proj_talon, Engine.espace, squelette ) );
			ikMoverOrteil.moveTo( Utils.PointLocalTransformation( proj_orteil, Engine.espace, squelette ) );
			
			//trace(proj_talon + " " + proj_orteil);
			//Main.drawings.graphics.clear();

			return new Segment( proj_talon, proj_orteil );
		}
		/*
		 * avec event.support : définit un nouveau support, une nouvelle liaison.
		 * sans event.support : fixe le pied à la liaison courante ( segment / obstacle )
		 * */
		public function colle( event:MoveEvent ):void
		{
			if ( event.support == null && support == null )
			{
				trace( "il faut un support pour pied.colle." );
				return;
			}
			if ( event.support != null )
			{
				support = event.support;
			}				
			move_plante( Utils.SegmentLocalTransformation( liaison.segment, liaison.obstacle.display, squelette ) );
		}
		public function deplace( event:MoveEvent ):void
		{
			//trace(this + "move " + event );
			fixed = null;
			
			move_plante( event.point as Segment );
			/*
			var hitted_obstacle:Obstacle = Engine.hit_pied( this );
			if ( hitted_obstacle != null )
			{
				trace( this + "\t touche \t" + hitted_obstacle );
				squelette.dispatchEvent( new MoveEvent( MoveEvent.CHANGEPIED, null, hitted_obstacle ) );
				fixed = pose( hitted_obstacle );
			}
			*/
		}
		
		// utils
		
		private function move_plante( _dp:Segment ):void
		{
			move( _dp.debut, _dp.fin );
		}
		private function move( _talon:Point, _orteil:Point ):void
		{
			ikMoverOrteil.moveTo( _orteil );
			ikMoverTalon.moveTo( _talon );
		}
		public function toString():String
		{
			return "Pied : " + ikBone.name;
		}	
	}	
}